import os
import time

from core.object import BarData, AccountData, OrderData, PositionData
from core.constant import *
from core.object import MessageData, DDQEmail
from tools.trade_server import base_from_dict, dict_from_base
from conf import conf
from datetime import datetime as datetime_
from datetime import timedelta


class TradeServer:
    def __init__(self, engine):
        self.engine = engine
        self.super_model = engine.super_model
        self.account = AccountData(conf.Fighting.default_account_id.value)
        self.order_dc: dict[str, OrderData] = {}
        self.message_dc = {}
        self.email_dc = {}
        self.ddq_email = DDQEmail()
        self.position_dc: dict[str, PositionData] = {}
        self.node_dc: dict[str, BarData] = {}
        self.now_time = None
        self.is_email: bool = False  # 是否发送邮件

    def set_is_email(self, is_email):
        self.is_email = is_email  # 邮件模式

    def set_account_init(self, balance, fee_rate):
        self.account.balance = balance
        self.account.fee_rate = fee_rate

    def send_test_email(self):
        """发送测试邮件至邮箱"""
        # 发送邮件
        subject = f"欢迎使用DDQ Fighting模块下Message功能，当前时间{datetime_.now().strftime('%m-%d %H:%M:%S')}"
        try:
            msg = self.ddq_email.send_email(subject, "DDQuant系列量化框架：https://gitee.com/benhe256/daydayquant")
            info = msg
            self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        except Exception as e:
            info = f"邮件发送错误，{e}"
            self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)

    def send_email(self, send_email_mode: SendEmailMode):
        if send_email_mode == SendEmailMode.OneMode and self.is_email:
            # 将email_dc中的message进行逐个发送
            for message_id, message in self.email_dc.items():
                if message.status in [Status.NOTTRADED, Status.PARTTRADED]:
                    # 发送消息
                    subject = f"DDQuant实时消息: 级别{message.level.value}"
                    email_context = (f"级别: {message.level.value},标的: {message.symbol},价格: {message.price}, "
                                     f"方向: {message.direction.value}, "
                                     f"时间: {message.datetime.strftime('%H:%M:%S')}"
                                     f"\n内容: {message.content}")
                    smg = self.ddq_email.send_email(subject, email_context)
                    if smg[0]:
                        # 标记消息为以处理
                        message.status = Status.ALLTRADED
                    else:
                        info = "消息处理失败，状态未更新。"
                        self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        elif send_email_mode == SendEmailMode.GroupMode and self.is_email:
            # 将email_dc中的message批量处理并发送
            content_ls = []
            level_ls = []
            for message_id, message in self.email_dc.items():
                if message.status in [Status.NOTTRADED, Status.PARTTRADED]:
                    content_o = message.to_str()
                    content_ls.append(content_o)
                    level_ls.append(message.level.value)
            level_set = set(level_ls)
            subject = f"DDQuant历史消息: 级别{'，'.join(level_set)}"
            email_context = '\n'.join(content_ls)
            smg = self.ddq_email.send_email(subject, email_context)
            if smg[0]:
                # 批量更新状态
                for message_id, message in self.email_dc.items():
                    if message.status in [Status.NOTTRADED, Status.PARTTRADED]:
                        message.status = Status.ALLTRADED
            else:
                info = "批量消息处理失败，状态未更新。"
                self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        pass

    def deal_message(self, message_data):
        self.pre_deal_message(message_data)
        self.message_dc[message_data.message_id] = message_data

        pass

    def pre_deal_message(self, message_data):

        pass

    def update_node_dc(self, node_dc: dict[str, BarData]):
        self.node_dc = node_dc
        self.update_time()

    def update_time(self):
        if self.super_model.fighting_mode in [FightingMode.LiveMessage.value, FightingMode.LiveSimulate.value, FightingMode.LiveReal.value]:
            self.now_time = datetime_.now()
        else:
            self.now_time = self.node_dc[list(self.node_dc.keys())[0]].datetime

    def update_messages_by_node(self, node_dc: dict[str, BarData]):
        # 遍历订单，改变订单信息，以及改变账户信息，仓位信息，bt交易信息
        for message_id, message in self.message_dc.items():
            message_status = message.status
            # ------------------------------  过滤已经处理完毕的订单  ---------------------------------
            if message_status in [Status.SUBMITTING, Status.PARTTRADED]:
                pass
            else:
                # 订单已经被完全处理
                continue
            # 筛选需要在当前条件进行处理的订单
            # -------------------------------  初步给予订单接受或被拒的状态  -------------------------------
            message.status = Status.NOTTRADED
            self.engine.template.notify_message(message)

            # -------------------------------  处理已经处于接受状态的订单  -------------------------------
            if message_status == Status.NOTTRADED:
                self.email_dc[message_id] = message
            else:
                continue

    def update_orders_by_node(self, node_dc: dict[str, BarData]):

        pass

    def before_open_accept(self, order: OrderData):

        pass

    def after_open_cancel(self, order: OrderData):

        pass

    def after_open_deal(self, order: OrderData):

        pass

    def before_close_accept(self, order: OrderData):

        pass

    def after_close_cancel(self, order: OrderData):

        pass

    def after_close_deal(self, order: OrderData):

        pass

    # 先by order再by bar
    def update_position_by_node(self, node_dc: dict[str, BarData]):

        pass

    def update_account_by_node(self, node_dc: dict[str, BarData]):
        # 根据仓位信息整合出当前的账户冻结资金信息

        pass

    def deal_order(self, order: OrderData):
        # 订单成交动作
        # 根据实际成交价格数量计算手续费

        # 改变position_dc及account
        pass

    def pre_deal_order(self, order: OrderData):
        # 预检查
        # 价格、数量数值纠正
        digit_num = len(str(conf.Fighting.price_digit.value).split('.')[1])

        if int(order.price * 10 ** digit_num) % int(conf.Fighting.price_digit.value * 10 ** digit_num) != 0:
            order.status = Status.REJECTED
            order.datetime = self.now_time
            self.engine.template.notify_order(order)

        pass

    def cancel_all_order(self):
        # 取消所有委托单

        pass

    def cancel_order(self, order_id: str):
        # 根据order id来撤销委托订单

        pass

    def buy(self):
        # 买

        pass

    def sell(self):
        # 卖

        pass

    def short(self):
        # 空

        pass

    def long(self):
        # 多

        pass

    def message(self):
        # 普通消息

        pass


class SimulateTrade(TradeServer):
    def __init__(self, engine):
        super().__init__(engine)

    def update_orders_by_node(self, node_dc: dict[str, BarData]):
        # 遍历订单，改变订单信息，以及改变账户信息，仓位信息，bt交易信息
        for order_id, order in self.order_dc.items():
            order_status = order.status
            # ------------------------------  过滤已经处理完毕的订单  ---------------------------------
            if order_status in [Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED]:
                pass
            else:
                # 订单已经被完全处理
                continue
            # 筛选需要在当前条件进行处理的订单
            # -------------------------------  初步给予订单接受或被拒的状态  -------------------------------
            # 订单不满足前置条件
            # 开仓单判断账户余额条件
            if order_status == Status.SUBMITTING and order.offset == Offset.OPEN:
                # 预先根据账户信息判断当前订单是否可以成交，确保可以成交再进行后续操作
                is_true = self.account.open_is_reasonable(order)
                # 改变状态
                if is_true:
                    self.before_open_accept(order)
                    order.status = Status.NOTTRADED
                    order.datetime = self.now_time
                    self.engine.template.notify_order(order)
                else:
                    order.status = Status.REJECTED
                    order.datetime = self.now_time
                    self.engine.template.notify_order(order)

                    # 订单已经被完全处理
                    continue
                # 若有仓位，要求开仓订单方向与现有仓位一致
                if order.symbol in self.position_dc.keys():
                    is_true = self.position_dc[order.symbol].open_pos_judge(order)
                    if is_true:
                        pass
                    else:
                        order.status = Status.REJECTED
                        order.datetime = self.now_time
                        self.engine.template.notify_order(order)

                        # 订单已经被完全处理
                        continue

            # 平仓单判断仓位可用余额及方向条件
            elif order_status == Status.SUBMITTING and order.offset == Offset.CLOSE:
                # -------------------------------------
                # 预先根据仓位信息判断当前订单是否可以成交，确保可以成交再进行后续操作
                position = self.position_dc[order.symbol]

                is_true = position.close_pos_judge(order)
                if is_true:
                    pass
                else:
                    order.status = Status.REJECTED
                    order.datetime = self.now_time
                    self.engine.template.notify_order(order)

                    continue  # 平仓订单被拒，执行下一个订单
                # -------------------------------------
                # 平仓单，提交后仅改变状态而不影响账户信息
                self.before_close_accept(order)
                # 改变状态
                order.status = Status.NOTTRADED
                order.datetime = self.now_time
                self.engine.template.notify_order(order)
            else:
                pass
            # -------------------------------  处理已经处于接受状态的订单  -------------------------------
            close_with_symbol = self.node_dc[order.symbol].close_price
            close_time = self.node_dc[order.symbol].datetime
            if order.status == Status.NOTTRADED and order.offset == Offset.OPEN:
                # --------------------------------------------------------------------------
                if order.type == OrderType.LIMIT:
                    # 若成交则改变order状态，修改account信息，修改position信息，修改trade信息
                    # 订单成交条件
                    deal_cond = (order.price > close_with_symbol and order.direction == Direction.LONG) or (order.price < close_with_symbol and order.direction == Direction.SHORT)
                    if deal_cond:
                        # 改变订单状态
                        self.before_open_deal(order)

                        order.status = Status.ALLTRADED
                        order.traded = order.volume
                        self.after_open_deal(order)
                        order.datetime = self.now_time
                        self.engine.template.notify_order(order)
                        self.engine.template.notify_trade(order)

                        continue
                    # 若不成交则等待保持等待
                    else:
                        lifespan_time = conf.Fighting.lifespan.value if order.lifespan_time is None else order.lifespan_time
                        # 委托单超期转失效单，默认订单创建时间为始，有效期在配置文件
                        if close_time > order.datetime + lifespan_time:
                            order.status = Status.CANCELLED
                            self.after_open_cancel(order)
                            order.datetime = self.now_time
                            self.engine.template.notify_order(order)
                            continue
                        pass
                # --------------------------------------------------------------------------
                elif order.type == OrderType.MARKET:
                    # 改变订单状态
                    self.before_open_deal(order)

                    order.status = Status.ALLTRADED
                    order.traded = order.volume
                    # 返还委托时的所有资金
                    # 市价单改变订单成交价为当前收盘价
                    if order.direction == Direction.SHORT:
                        order.price = close_with_symbol - conf.Fighting.slippage.value
                    elif order.direction == Direction.LONG:
                        order.price = close_with_symbol + conf.Fighting.slippage.value
                    else:
                        raise ValueError("方向逻辑错误。")
                    self.after_open_deal(order)
                    order.datetime = self.now_time
                    self.engine.template.notify_order(order)
                    self.engine.template.notify_trade(order)

                    continue

            elif order.status == Status.NOTTRADED and order.offset == Offset.CLOSE:

                # 平仓单，需要在订单处理完毕后再反馈至账户
                # --------------------------------------------------------------------------
                if order.type == OrderType.LIMIT:
                    # 若成交则改变order状态，修改account信息，修改position信息，修改trade信息
                    if (order.price > close_with_symbol and order.direction == Direction.LONG) or (order.price < close_with_symbol and order.direction == Direction.SHORT):
                        # 改变订单状态
                        order.status = Status.ALLTRADED
                        order.traded = order.volume
                        self.after_close_deal(order)
                        order.datetime = self.now_time
                        self.engine.template.notify_order(order)
                        self.engine.template.notify_trade(order)

                        continue
                    # 若不成交则等待保持等待
                    else:
                        lifespan_time = conf.Fighting.lifespan.value if order.lifespan_time is None else order.lifespan_time
                        # 委托单超期转失效单，默认订单创建时间为始，有效期在配置文件
                        if close_time > order.datetime + lifespan_time:
                            order.status = Status.CANCELLED
                            self.after_close_cancel(order)
                            order.datetime = self.now_time
                            self.engine.template.notify_order(order)

                            continue
                # --------------------------------------------------------------------------
                elif order.type == OrderType.MARKET:
                    # 改变订单状态
                    order.status = Status.ALLTRADED
                    order.traded = order.volume
                    # 市价单改变订单成交价为当前收盘价（考虑滑点）
                    if order.direction == Direction.SHORT:
                        order.price = close_with_symbol - conf.Fighting.slippage.value
                    elif order.direction == Direction.LONG:
                        order.price = close_with_symbol + conf.Fighting.slippage.value
                    else:
                        raise ValueError("逻辑错误。")
                    self.after_close_deal(order)
                    order.datetime = self.now_time
                    self.engine.template.notify_order(order)
                    self.engine.template.notify_trade(order)


                    continue
            else:
                continue

    def before_open_accept(self, order: OrderData):
        # 调用账户方法
        self.account.before_open_accept(order)
        # 调用仓位方法  无

    def after_open_cancel(self, order: OrderData):
        # 调用仓位方法  无

        # 调用账户方法
        self.account.after_open_cancel(order)

    def before_open_deal(self, order: OrderData):
        self.account.before_open_deal(order)

    def after_open_deal(self, order: OrderData):
        # 调用账户方法
        self.account.after_open_deal(order)
        # 调用仓位方法
        if order.symbol not in self.position_dc.keys():
            position = PositionData(symbol=order.symbol, exchange=Exchange.DDQ, direction=order.direction,
                                    volume=0, price=0)
            self.position_dc[order.symbol] = position
        else:
            position = self.position_dc[order.symbol]
        position.after_open_deal(order)
        # 将订单信息转为相应消息信息并存储
        price = order.price
        direction: Direction = order.direction
        level: Level = Level.Normal
        content = f"{order.offset.value}仓单，{order.direction}单成交。"
        datetime: datetime_ = self.now_time
        message_id = '_'.join([order.symbol, datetime.strftime("%y-%m-%d_%H-%M-%S")])
        message_data = MessageData(message_id=message_id, symbol=order.symbol, price=price, direction=direction,
                                   level=level, content=content, table=None, datetime=datetime, am=None)
        self.deal_message(message_data)

    def before_close_accept(self, order: OrderData):
        # 调用仓位方法
        if order.symbol not in self.position_dc.keys():
            raise ValueError("平仓前无相关仓位，逻辑错误。")
        else:
            position = self.position_dc[order.symbol]
        position.before_close_accept(order)

        # 调用账户方法
        self.account.before_close_accept(order)

    def after_close_cancel(self, order: OrderData):
        # 调用仓位方法
        if order.symbol not in self.position_dc.keys():
            raise ValueError(f"平仓单取消后的动作，之前无{order.symbol}对应的仓位，逻辑错误。")
        else:
            position = self.position_dc[order.symbol]
        position.after_close_cancel(order)

        # 调用账户方法
        self.account.after_close_cancel(order)

    def after_close_deal(self, order: OrderData):
        # 调用仓位方法
        if order.symbol not in self.position_dc.keys():
            raise ValueError(f"平仓单成交后的动作，之前无{order.symbol}对应的仓位，逻辑错误。")
        else:
            position = self.position_dc[order.symbol]
        instruct = position.after_close_deal(order)
        if instruct == "pop":
            self.position_dc.pop(order.symbol)
        # 调用账户方法
        self.account.after_close_deal(order)
        # 将订单信息转为相应消息信息并存储
        price = order.price
        direction: Direction = order.direction
        level: Level = Level.Normal
        content = f"{order.offset.value}仓单，{order.direction}单成交。"
        datetime: datetime_ = self.now_time
        message_id = '_'.join([order.symbol, datetime.strftime("%y-%m-%d_%H-%M-%S")])
        message_data = MessageData(message_id=message_id, symbol=order.symbol, price=price, direction=direction,
                                   level=level, content=content, table=None, datetime=datetime, am=None)
        self.deal_message(message_data)

    # 先by order再by bar
    def update_position_by_node(self, node_dc: dict[str, BarData]):
        for symbol, bar in node_dc.items():
            # 根据bar更新frozen、pnl、yd_volume(Yesterday's Volume)
            for symbol_o, position_o in self.position_dc.items():
                if symbol == symbol_o:
                    # 预留！ 根据冻结规则，确定更改仓位冻结数量的逻辑
                    # if ...
                    # 更改盈利
                    if position_o.direction == Direction.LONG:
                        position_o.pnl = (bar.close_price - position_o.price) * position_o.volume
                    elif position_o.direction == Direction.SHORT:
                        position_o.pnl = (position_o.price - bar.close_price) * position_o.volume
                    else:
                        raise ValueError("仓位方向逻辑错误。")
                    # 预留！ yd_volume逻辑待定
                    pass
                    break  # 找到symbol后，剩余的循环没有意义

        pass

    def update_account_by_node(self, node_dc: dict[str, BarData]):
        # 根据仓位信息整合出当前的账户冻结资金信息
        frozen_fund = 0
        for symbol_o, position_o in self.position_dc.items():
            frozen_fund += position_o.volume*position_o.price + position_o.pnl
        self.account.frozen = frozen_fund
        self.account.datetime = node_dc[list(node_dc.keys())[0]].datetime
        pass

    def deal_order(self, order: OrderData):
        # 加入订单列表
        self.order_dc[order.orderid] = order

        pass

    def cancel_all_order(self):
        # 取消所有委托单
        for order_id, order in self.order_dc.items():
            if order.status in [Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED]:
                order.status = Status.CANCELLED
                order.datetime = self.now_time
                self.engine.template.notify_order(order)

        pass

    def cancel_order(self, order_id: str):
        # 根据order id来撤销委托订单
        if order_id in self.order_dc.keys():
            order = self.order_dc[order_id]
            if order.status in [Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED]:
                order.status = Status.CANCELLED
                order.datetime = self.now_time
                self.engine.template.notify_order(order)

            else:
                info = "order id存在，但相应订单当前状态不满足。"
                self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        else:
            info = "order id不存在。"
            self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        pass

    def buy(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = self.now_time

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.LONG
        offset = Offset.OPEN

        # 买
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)
        pass

    def sell(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = self.now_time

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.SHORT
        offset = Offset.CLOSE

        # 卖
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)
        pass

    def short(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = self.now_time

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.SHORT
        offset = Offset.OPEN

        # 空
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)

        pass

    def long(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = self.now_time

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.LONG
        offset = Offset.CLOSE

        # 多
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)

        pass


class MessageTrade(TradeServer):
    def __init__(self, engine):
        super().__init__(engine)

    def buy(self, symbol=None, level=None, content=None, table=None, am=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if level is None:
            level = Level.Normal
        if content is None:
            content = "买入消息"
        if table is None:
            table = []
        if am is None:
            am = None
        price = self.node_dc[symbol].close_price
        direction: Direction = Direction.LONG
        datetime: datetime_ = self.now_time
        message_id = '_'.join([symbol, datetime.strftime("%y-%m-%d_%H-%M-%S")])
        message_data = MessageData(message_id=message_id, symbol=symbol, price=price, direction=direction, level=level,
                                   content=content, table=table, datetime=datetime, am=am)
        self.deal_message(message_data)

    def sell(self, symbol=None, level=None, content=None, table=None, am=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if level is None:
            level = Level.Normal
        if content is None:
            content = "卖出消息"
        if table is None:
            table = []
        if am is None:
            am = None
        price = self.node_dc[symbol].close_price
        direction: Direction = Direction.SHORT
        datetime: datetime_ = self.now_time
        message_id = '_'.join([symbol, datetime.strftime("%y-%m-%d_%H-%M-%S")])
        message_data = MessageData(message_id=message_id, symbol=symbol, price=price, direction=direction, level=level,
                                   content=content, table=table, datetime=datetime, am=am)
        self.deal_message(message_data)
        pass

    def message(self, symbol=None, level=None, content=None, table=None, am=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if level is None:
            level = Level.Normal
        if content is None:
            content = "提示消息"
        if table is None:
            table = []
        if am is None:
            am = None
        price = self.node_dc[symbol].close_price
        direction: Direction = Direction.MIDDLE
        datetime: datetime_ = self.now_time
        message_id = '_'.join([symbol, datetime.strftime("%y-%m-%d_%H-%M-%S")])
        message_data = MessageData(message_id=message_id, symbol=symbol, price=price, direction=direction, level=level,
                                   content=content, table=table, datetime=datetime, am=am)
        self.deal_message(message_data)
        pass


class RealTrade(TradeServer):
    def __init__(self, engine):
        super().__init__(engine)
        self.trade_server_path = None
        self.ddq_orders_path = None
        self.trade_server_dc = None
        self.is_monitor = False  # 标记是否检测
        self.json_modify_time = None

    def on_order_update(self, new_order_dc: dict[str, OrderData]):
        # 对比新旧数据，根据变化的部分给出具体的逻辑
        # 检测到变化的order
        for order_id, order in new_order_dc.items():
            old_order = self.order_dc[order_id]
            is_changed = order.traded != old_order.traded or order.status != order.status
            if is_changed:
                order.datetime = self.now_time
                self.engine.template.notify_order(order)
                if order.status == Status.ALLTRADED:
                    self.engine.template.notify_trade(order)
        # 更新订单字典
        self.order_dc = new_order_dc
        pass

    def on_position_update(self, new_position_dc: dict[str, PositionData]):
        # 对比新旧数据，根据变化的部分给出具体的逻辑
        # 检测到变化的position
        for position_id, position in new_position_dc.items():
            old_position = self.position_dc[position_id]
            is_changed = position.volume != old_position.volume
            if is_changed:
                self.engine.template.notify_position(position)
        # 更新仓位字典
        self.position_dc = new_position_dc
        pass

    def on_account_update(self, new_account: AccountData):
        # 对比新旧数据，根据变化的部分给出具体的逻辑
        # 逻辑简单，仅需将新数据覆盖到老数据
        # 更新账户字典
        self.account = new_account
        pass

    def update_order(self, new_order: OrderData):
        # 主动更新订单信息
        # 接收template的订单变动信息并综合处理
        order_dc = {}
        if new_order.orderid not in self.order_dc.keys():  # 新增订单的情况
            if new_order.status == Status.SUBMITTING:
                order_dc[new_order.orderid] = new_order
            else:
                print(f"订单{new_order.orderid}在准备加入ddq订单列表前不为submitting。")
        else:  # 订单已经存在的情况
            if new_order.status == Status.CANCELLED:  # 订单发生撤销的情况
                order_dc[new_order.orderid] = new_order
            else:
                raise ValueError("未预先考虑的订单改动类型。")
        self.super_model.master.file_manager.save_json(order_dc, self.ddq_orders_path)

        pass

    def monitor(self, data_path):
        # 即时检测trade server的变化
        self.is_monitor = True
        pass

    def monitor_thread(self):
        software_path = conf.DataBridge.software_path
        retry_time = 10
        num = 0
        while True:
            if self.trade_server_path is None:  # 这是行情到来后第一个传递到的回调函数，所以在此处赋值
                self.trade_server_path = os.path.join(software_path, "bin.x64", "trade_server.json")
                self.ddq_orders_path = os.path.join(software_path, "bin.x64", "ddq_orders.json")

            if os.path.exists(self.trade_server_path):
                self.trade_server_dc: dict = self.super_model.master.file_manager.read_json(self.trade_server_path)
                self.order_dc, self.position_dc, self.account = base_from_dict(self.trade_server_dc)
                self.json_modify_time = datetime_.fromtimestamp(os.path.getmtime(self.trade_server_path))
                break
            else:
                num += 1
                if num >= retry_time:
                    info = f"重试{retry_time}次仍未监测到交易服务接口文件，线程结束。"
                    self.super_model.master.file_manager.log_engine(info, LogName.Operate)
                    return
                info = f"未监测到交易服务接口文件，将在{conf.DataBridge.monitor_period.value.total_seconds()}秒后重试。"
                self.super_model.master.file_manager.log_engine(info, LogName.Operate)
                time.sleep(conf.DataBridge.monitor_period.value.total_seconds())
        # 循环检测trade server
        retry_time = 0
        while True:
            # 监测trade server文件
            json_modify_time = datetime_.fromtimestamp(os.path.getmtime(self.trade_server_path))
            if json_modify_time > self.json_modify_time:
                # 更新获取trade server json文件的信息
                self.trade_server_dc: dict = self.super_model.master.file_manager.read_json(self.trade_server_path)
                order_dc, position_dc, account = base_from_dict(self.trade_server_dc)
                self.json_modify_time = json_modify_time

                # 调用相关回调函数
                # 订单改变回调
                self.on_order_update(order_dc)
                # 仓位改变回调
                self.on_position_update(position_dc)
                # 账户改变回调
                self.on_account_update(account)
                retry_time = 0
            else:
                retry_time += 1
                tip_period = 180
                if retry_time * conf.DataBridge.monitor_period.value.total_seconds() > tip_period:
                    info = f"距上次提示消息已有{round(tip_period / 60, 1)}分钟，请注意。"
                    self.super_model.master.file_manager.log_engine(info, LogName.Operate)
                    retry_time = 0
            if self.is_monitor:
                time.sleep(conf.DataBridge.monitor_period.value.total_seconds())
            else:
                info = f"监测标志为否，线程结束。"
                self.super_model.master.file_manager.log_engine(info, LogName.Operate)
                break

    def deal_order(self, order: OrderData):
        # 接收template的订单，并将其改动应用到trade server
        if order.status == Status.REJECTED:
            self.order_dc[order.orderid] = order
            return
        # 订单改变回调，更新订单信息主动推送到交易端
        self.update_order(order)
        # 仓位改变回调，更新仓位信息主动推送到交易端（ddq无法主动更新仓位信息）

        # 账户改变回调，更新账户信息主动推送到交易端（ddq无法主动更新账户信息）

        pass

    def cancel_all_order(self):
        # 取消所有委托单
        for order_id, order in self.order_dc.items():
            if order.status in [Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED]:
                order.status = Status.CANCELLED

        pass

    def cancel_order(self, order_id: str):
        # 根据order id来撤销委托订单
        if order_id in self.order_dc.keys():
            order = self.order_dc[order_id]
            if order.status in [Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED]:
                order.status = Status
            else:
                info = "order id存在，但相应订单当前状态不满足。"
                self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        else:
            info = "order id不存在。"
            self.super_model.master.file_manager.log_engine.emit(info, LogName.Running)
        pass

    def buy(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = datetime_.now()

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.LONG
        offset = Offset.OPEN
        # 买
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)
        pass

    def sell(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = datetime_.now()

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.SHORT
        offset = Offset.CLOSE
        # 卖
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)
        pass

    def short(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = datetime_.now()

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.SHORT
        offset = Offset.OPEN
        # 空
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)

        pass

    def long(self, symbol=None, price=None, volume=None, type=None, lifespan_time=None):
        if symbol is None:
            symbol = conf.Model.DefaultSymbol.value
        if volume is None:
            volume = 1
        if type is None:
            type = OrderType.MARKET
        if price is None:
            price = self.node_dc[symbol].close_price
        if lifespan_time is None:
            lifespan_time = timedelta(days=1)
        exchange = Exchange.DDQ
        datetime = datetime_.now()

        order_id = f"{symbol}-{datetime.strftime('%y%m%d%H%M%S')}"
        direction = Direction.LONG
        offset = Offset.CLOSE
        # 多
        order = OrderData(symbol, exchange, order_id, type, direction, offset, price, volume,
                          traded=0, commission=0, status=Status.SUBMITTING, datetime=datetime,
                          lifespan_time=lifespan_time)
        self.pre_deal_order(order)
        self.deal_order(order)

        pass

